package org.benetech.collections;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;

import org.benetech.beans.Filter;
import org.benetech.beans.FilterCallback;

/**
 * Adapts an existing filter for use in filtering a tree.
 * @author Reuben Firmin
 * @param <T> The primary content type of the tree
 * @param <U> The callback type
 * @see Filter
 */
public final class TreeFilter<T, U> implements Filter<Tree<T, ? , ? >, U> {

	private Filter<T, U> delegate;

	/**
	 * Construct this tree filter, with an existing filter as delegate.
	 * @param delegate Not null
	 */
	public TreeFilter(final Filter<T, U> delegate) {
		this.delegate = delegate;
	}

	/**
	 * {@inheritDoc}
	 */
	public boolean acceptWithCallback(final FilterCallback<U> callback, final Tree<T, ? , ? >... items) {
		final List<T> itemContents = new ArrayList<T>();
		Class contentClass = null;
		if (items != null) {
			for (final Tree<T, ? , ? > tree : items) {
				itemContents.add(tree.getContent());
				contentClass = tree.getContentClass();
			}
			return delegate.acceptWithCallback(callback, itemContents.toArray(
					(T[]) Array.newInstance(contentClass, 0)));
		}
		return delegate.acceptWithCallback(callback, null);
	}

	/**
	 * {@inheritDoc}
	 */
	public boolean accept(final Tree<T, ? , ? >... items) {
		return acceptWithCallback(null, items);
    }
}

